﻿using System;
using CSW.Framework.Common;
using CSW.Framework.Linq.SchemaModel;

namespace CSW.Framework.Linq.QueryModel
{
    /// <summary>
    /// Container
    /// </summary>
    public class Container
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Container"/> class.
        /// </summary>
        /// <param name="parentProperty">The parent property.</param>
        /// <param name="table">The table.</param>
        public Container(Property parentProperty, Table table)
        {
            //Guard.ArgumentNotNull(parentProperty, "parentProperty");
            Guard.ArgumentNotNull(table, "table");

            ParentProperty = parentProperty;
            Table = table;

            TableColumn[] primaryKeys = Table.PrimaryKey;
            if (primaryKeys.Length == 0)
                throw new Exception(string.Format("No primary key found on '{0}'.", Table));
            else if (primaryKeys.Length > 1)
                throw new NotImplementedException(string.Format("Composite primary key found on '{0}'. Composite keys are not supported.", Table));
            
            JoinColumn = primaryKeys[0];
            IsReverse = false;

            //ObjectCounter.Add(this);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Container"/> class.
        /// </summary>
        /// <param name="parentProperty">The parent property.</param>
        /// <param name="table">The table.</param>
        /// <param name="joinColumn">The join column.</param>
        public Container(Property parentProperty, Table table, TableColumn joinColumn)
        {
            //Guard.ArgumentNotNull(parentProperty, "parentProperty");
            Guard.ArgumentNotNull(table, "table");
            Guard.ArgumentNotNull(joinColumn, "joinColumn");

            ParentProperty = parentProperty;
            Table = table;
            JoinColumn = joinColumn;
            IsReverse = true;

            //ObjectCounter.Add(this);
        }

        /*/// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="Container"/> is reclaimed by garbage collection.
        /// </summary>
        ~Container()
        {
            ObjectCounter.Remove(this);
        }*/

        /// <summary>
        /// Gets the parent property.
        /// </summary>
        /// <value>The parent property.</value>
        public Property ParentProperty { get; private set; }

        /// <summary>
        /// Gets the join column.
        /// </summary>
        /// <value>The join column.</value>
        public TableColumn JoinColumn { get; private set; }

        /// <summary>
        /// Gets or sets the table alias.
        /// </summary>
        /// <value>The table alias.</value>
        public string TableAlias { get; internal set; }

        /// <summary>
        /// Gets the table.
        /// </summary>
        /// <value>The table.</value>
        public Table Table { get; private set; }

        /// <summary>
        /// Gets a value indicating whether this instance is a reverse lookup.
        /// </summary>
        /// <value><c>true</c> if this instance is a reverse lookup; otherwise, <c>false</c>.</value>
        public bool IsReverse { get; private set; }

        /// <summary>
        /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <returns>A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.</returns>
        public override string ToString()
        {
            return string.Format("{0}, {1}", Table, ParentProperty);
        }
    }
}